/*
 * Improbability Drive
 * Phillip Cardon, Thach Nguyen, Cristopher Claeys
 * 4/26/2011
 */

package structures;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.Observable;

import ui.Launcher;

/**
 * Reporter class, alerts the owner of its listener when changes are made to it.
 * 
 * @author Cristopher Claeys
 */
public class Reporter extends Observable {
	/**
	 * An array of the keywords to search for.
	 */
	private final String[] keys;
	
	/**
	 * The current total word count.
	 */
	private int words;
	
	/**
	 * The current total link count.
	 */
	private int links;
	
	/**
	 * The latest parsed URL.
	 */
	private URL latest;
	
	/**
	 * An array of ints representing the count of each keyword with corresponding indexes. 
	 */
	private int[] count;
	
	/**
	 * Current count of the pages parsed so far.
	 */
	private int pages;
	
	/**
	 * Property change support
	 */
	private final PropertyChangeSupport pcs = new PropertyChangeSupport(pages);
	
	/**
	 * Page crawler limit
	 */
	private final int page_limit;
	
	/**
	 * The total time spent parsing
	 */
	private long total_parse_time;
	
	public Reporter(String[] key_list, int limit) {
		keys = key_list;
		page_limit = limit;
	}
	
	/**
	 * Adds a listener
	 * 
	 * @param l the listener
	 */
	public void addListener(PropertyChangeListener l) {
		  pcs.addPropertyChangeListener(l);
	}
	
	/**
	 * Updates the info to report
	 * 
	 * @param words_new The new word count
	 * @param links_new The new link count
	 * @param latest_new The newest URL
	 * @param count_new The new keyword count
	 * @param pages_new The total pages visited
	 * @param parse_time The total parse time so far
	 */
	public void update(int words_new, int links_new, URL latest_new,
					   int[] count_new, int pages_new, long parse_time)
	{
		setChanged();
		int old = pages;
		words = words_new;
		links = links_new;
		latest = latest_new;
		count = count_new;
		pages = pages_new;
		total_parse_time = parse_time;
		pcs.firePropertyChange("updated", old, pages);
		//System.out.println("update called");
		notifyObservers();
	}
	
	/**
	 * Returns the desired reporting output.
	 * 
	 * @return the string representation of the reporter.
	 */
	public String toString() {
		StringBuilder build = new StringBuilder();
		build.append("Parsed: " + latest + "\n");
		build.append("Pages Retrieved: " + pages + "\n");
		build.append("Average words per page: " + (words/pages) + "\n");
		build.append("Average URLs per page: " + (links/pages) + "\n");
		build.append("Keyword\tAve. hits per page\tTotal hits\n");
		for(int i = 0; i < keys.length; i++) {
			build.append(keys[i] + "\t" + count[i]/(double)(pages) + "\t" + count[i] + "\n");
		}
		build.append("\nPage limit: " + page_limit +"\n");
		build.append("Average parse time per page: " + new DecimalFormat("#.####").format(total_parse_time/(double)pages)
				+ "msec\n");
		return build.toString();
	}
	
	public int getPageLimit() {
		return page_limit;
	}
	
	public int getPages() {
		return pages;
	}

}
